我(在reverse题中)最讨厌的语言——go。
被ida里出现的奇怪结构体吓晕。
main函数在cutter里怎么是runtime.text啊(不过在sym.runtime.main里被调用了)。
首先,整个程序被包裹在一个大大的死循环中,然后不断scanf %d。当读到EOF的时候停止,判断是不是13个数字(表面上,实际上是12个)数字。
如果当前数字不是eof,就会被append到数组里(下标甚至从1开始,第0位是0)。还有一个用来统计每个数字出现次数的数组,只能出现一次。
check的过程是这样的,因为中间有一大堆判断数组是否越界的语句(已删),所以容易被搞晕,导致看不到var_1e8h的初值。
1 2 3 4 5 6 7 8 9 10 11 12 13
| var_1e8h = 1; uVar5 = 1; do { uVar2 = *(uint64_t *)(var_18h + uVar5 * 8); var_1e8h = ((&var_168h)[uVar2] + -1) * (&var_1d0h)[var_1e0h - uVar5] + var_1e8h;
uVar2 = *(uint64_t *)(var_18h + uVar5 * 8); while (uVar2 = uVar2 + 1, (int64_t)uVar2 <= var_1e0h) { (&var_168h)[uVar2] = (&var_168h)[uVar2] + -1; } uVar4 = (uint32_t)uVar2; uVar5 = uVar5 + 1; } while ((int64_t)uVar5 <= var_1e0h);
|
换成python就是(写的时候把数组哪个是哪个弄错了,对着汇编改的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| def check(inpt): len_nums = 0xd v1d0h = [1,1,2,6,0x18,0x78,0x02d0,0x13b0,0x9d80,0x058980,0x375f00,0x02611500,0x1c8cfc00]
v18h = [] v168h = list(range(0xd))
for i in inpt: v18h.append(i)
i = 1 s = 1 while True: r11 = v18h r8 = r11[i] rbx = v168h[r8]-1 r8=len_nums-1-i rbp = v1d0h[r8] s += (rbx*rbp) j = v18h[i]+1 while j<=len_nums-1: v168h[j] -= 1 j+=1 i+=1 if i > len_nums -1: break print(hex(s)) return s == 0xe37f550
|
之后的正解大概是一个数学问题。https://dakutenpura.hatenablog.com/entry/2016/06/28/030236
不过我不会,于是打了暴搜,搜permutations(range(0,13))
,卡爆了。
但是经过观察发现,s竟然从1开始,每次增加1。于是就变成了:
1 2 3 4 5 6 7 8
| j = 0 for i in permutations(range(0,13)): j += 1 if j == 0xe37f550: print(check(i)) print(i) break
|